package org.spring.context.support;

import org.spring.beans.BeanDefinition;
import org.spring.beans.factory.annotation.AutowiredAnnotationProcessor;
import org.spring.beans.factory.config.ConfigurableBeanFactory;
import org.spring.beans.factory.support.DefaultBeanFactory;
import org.spring.beans.factory.xml.XmlBeanDefinitionReader;
import org.spring.context.ApplicationContext;
import org.spring.core.io.ClassPathResource;
import org.spring.core.io.Resource;
import org.spring.utils.ClassUtils;

import java.io.IOException;

public abstract class AbstractApplicationContext implements ApplicationContext {

    private DefaultBeanFactory beanFactory;
    private ClassLoader beanClassLoader;

    public AbstractApplicationContext(String configFile) throws IOException {
        beanFactory = new DefaultBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
        Resource classPathResource = getResourcePath(configFile);
        xmlBeanDefinitionReader.loadBeanDefinitions(classPathResource);
        beanFactory.setBeanClassLoader(this.getBeanClassLoader());
    }

    @Override
    public BeanDefinition getBeanDefinition(String beanId) {
        return beanFactory.getBeanDefinition(beanId);
    }

    @Override
    public Object getBean(String beanId) {
        return beanFactory.getBean(beanId);
    }

    public abstract Resource getResourcePath(String path);

    public void setBeanClassLoader(ClassLoader classLoader) {
        this.beanClassLoader = classLoader;
    }

    public ClassLoader getBeanClassLoader() {
        return (this.beanClassLoader != null ? this.beanClassLoader : ClassUtils.getDefaultClassLoader());
    }

    protected void registerBeanPostProcessors(ConfigurableBeanFactory beanFactory) {

        AutowiredAnnotationProcessor postProcessor = new AutowiredAnnotationProcessor();
        postProcessor.setBeanFactory(beanFactory);
        beanFactory.addBeanPostProcessor(postProcessor);

    }
}
